package snafu.framework.actions;

import snafu.framework.agents.ReactingAgent;
import snafu.framework.objects.WorldObject;
import snafu.framework.worlds.WorldMap;


public class AbstractReaction {

	private AbstractAction action;

	/**
	 * Creates the reaction with an executer, the action that created the reaction and the intention
	 * that shall be used for creating the reaction action.
	 * 
	 * @param executer
	 *            the world object that initiated the reaction
	 * @param action
	 *            the action that created the reaction. it's agent will be set as the reactions
	 *            target
	 * @param intention
	 *            the intention that shall create the reaction
	 */
	public AbstractReaction(WorldObject executer, AbstractAction action, IntentionItself<?> intention) {
		this.action = intention.createAction(action.getAgent());
		this.action.setAgent(new ReactingAgent(executer, intention));
	}
	
	/**
	 * Will execute the reaction on the given world map through the {@code execute()} method from
	 * the created action.
	 * 
	 * @param worldMap
	 *            the world map
	 */
	public void execute(WorldMap worldMap) {
		action.prepareAndExecute(worldMap);
	}
	
	/**
	 * Indicates whether the action is applicable given the current state of the world. Will use the
	 * method Intention#isApplicable(WorldMap, AgentState, List) of the intention attached to this
	 * action to determine this value.
	 * 
	 * @param worldMap
	 *            the world map
	 */
	public boolean isApplicable(WorldMap worldMap) {
		return action.isApplicable(worldMap);
	}
	
	@Override
	public String toString() {
		return "reaction: " + action;
	}
	
}
